package scales.xml.impl
import scala.collection.immutable.Map
import scala.collection.generic.CanBuildFrom
import scales.utils.{TreeCBF, subtree, item, top,
ItemOrTree, noPath => fno,
EitherLike, LeftLike}
import scales.utils.collection.{ListSet, Tree,
ImmutableArrayProxy, ImmutableArrayProxyBuilder }
import scales.utils.collection.path.{ Path, Position, Node }
import scales.xml.{XmlItem, Elem, Comment,
PI, QName, PrefixedQName,
NoNamespaceQName, Attribute,
ScalesXml}
trait XmlTypes {
import EqualsHelpers._
type XmlCBF = TreeCBF[XmlItem, Elem, XCC]
type AttributeQName = EitherLike[PrefixedQName, NoNamespaceQName]
type XmlBuilder = collection.mutable.Builder[ ItemOrElem, XmlChildren ]
def XmlBuilder() : XmlBuilder = ImmutableArrayProxyBuilder[ItemOrElem]()
type XmlTree = Tree[XmlItem, Elem, XCC]
type ItemOrElem = ItemOrTree[XmlItem, Elem, XCC]
type XmlChildren = XCC[ItemOrElem]
type XCC[T] = ImmutableArrayProxy[T]
type Misc = Either[Comment, PI]
type Miscs = Seq[Misc]
type Attributes = scales.utils.collection.ArraySet[Attribute]
val emptyMiscs: Miscs = List[Misc]()
val emptyAttributes: Attributes = AttributeSet.empty
val emptyNamespaces: Map[String, String] = Map[String, String]()
val emptyChildren: XmlChildren = ImmutableArrayProxy[ItemOrElem]()
val noXmlPath: XmlPath = fno[XmlItem, Elem, XCC]
type XmlPath = Path[XmlItem, Elem, XCC]
def ElemMatcher(name: QName, attributes: AttributeQName*) = new {
import ExtraTypesImplicits._
def matchAttribs(elem: Elem) = for (attribute <- attributes; matches <- elem.attributes(attribute)) yield matches
def unapply(elem: Elem): Option[(Elem, List[Attribute])] = {
val matched = matchAttribs(elem)
if (elem.name =:= name && matched.size == attributes.size)
Some((elem, matched.toList))
else
None
}
}
final def addAndFocus(path: XmlPath, elem: Elem, dchildren : XmlChildren = emptyChildren) =
if (path eq noXmlPath) {
top(Tree(
elem, dchildren))
} else {
import ScalesXml.xmlCBF
val n : ItemOrElem = subtree(elem, dchildren)
var size = 0
import path.node.focus
val parent = focus.getRight
val c = parent.children
size = c.length
val tpath = Path( path.top,
Node( path.node.index,
Tree(parent.section,
c :+ n)) )
Path(tpath, Node(size, n))
}
final def addChild(path: XmlPath, child: XmlItem) = {
import ScalesXml.xmlCBF
import path.node.focus
val parent = focus.getRight
Path( path.top,
Node( path.node.index,
Tree(parent.section,
parent.children :+ item[XmlItem, Elem, XCC](child))
))
}
}